"""
回测服务
基于 DeepSeek + Al Brooks 视觉分析进行历史回测
"""

from datetime import datetime, timedelta
from typing import Dict, List, Optional, Tuple
from ..services.binance_client import BinanceDataClient, SUPPORTED_INTERVALS
from ..services.chart_service import ChartService
from ..services.ai_strategy_service import AIStrategyService
from ..services.indicators import calculate_ema, calculate_macd, calculate_atr
from ..config import config


class BacktestingService:
    """回测服务"""

    def __init__(self) -> None:
        """初始化回测服务"""
        self.binance_client = BinanceDataClient()
        self.chart_service = ChartService()
        self.ai_service = AIStrategyService()

    def run_backtesting(
        self,
        symbol: str,
        start_time: str,
        end_time: str,
        interval: SUPPORTED_INTERVALS = '15m',
        profitStop: float = 20.0,
        enableTrendReversal: bool = True,
        enableDrawdownProtection: bool = True,
        enableSmartTrailing: bool = True,
        reversalSensitivity: str = 'medium'
    ) -> Dict:
        """
        运行回测

        Args:
            symbol: 交易对符号
            start_time: 开始时间 (YYYY-MM-DD)
            end_time: 结束时间 (YYYY-MM-DD)
            interval: 时间周期
            profitStop: 移动止盈触发百分比（默认20%，盈利达到此比例时激活移动止盈）
            enableTrendReversal: 是否启用趋势反转检测（默认True）
            enableDrawdownProtection: 是否启用动态回撤保护（默认True）
            enableSmartTrailing: 是否启用智能移动止损（默认True）
            reversalSensitivity: 反转检测灵敏度 ('low', 'medium', 'high')

        Returns:
            回测结果
        """
        try:
            # 1. 解析时间
            start_dt = datetime.strptime(start_time, '%Y-%m-%d')
            end_dt = datetime.strptime(end_time, '%Y-%m-%d')
            end_dt = end_dt + timedelta(days=1)  # 包含结束日期全天

            # 2. 获取历史K线数据
            klines = self.binance_client.get_klines(
                symbol=symbol,
                interval=interval,
                start_time=start_dt,
                end_time=end_dt,
                limit=1500  # 最大限制
            )

            if not klines:
                raise ValueError(f"未获取到 {symbol} 在 {start_time} 到 {end_time} 期间的K线数据")

            # 3. 执行回测逻辑
            trades, analysis_count = self._execute_backtesting(
                symbol, klines, interval, profitStop,
                enableTrendReversal, enableDrawdownProtection,
                enableSmartTrailing, reversalSensitivity
            )

            # 4. 计算总盈亏
            total_profit = sum(trade['profit'] for trade in trades)

            return {
                'code': 200,
                'data': {
                    'interval': interval,
                    'symbol': symbol,
                    'trades': trades,
                    'totalProfitUsdt': int(total_profit),
                    'analysisCount': analysis_count
                },
                'msg': 'success'
            }

        except Exception as e:
            return {
                'code': 500,
                'data': {},
                'msg': f'回测失败: {str(e)}'
            }

    def _execute_backtesting(
        self,
        symbol: str,
        klines: List[Dict],
        interval: str,
        profitStop: float,
        enableTrendReversal: bool,
        enableDrawdownProtection: bool,
        enableSmartTrailing: bool,
        reversalSensitivity: str
    ) -> Tuple[List[Dict], int]:
        """
        执行回测逻辑（滑动窗口递增算法）

        Args:
            symbol: 交易对
            klines: K线数据
            interval: 时间周期
            profitStop: 移动止盈触发百分比
            enableTrendReversal: 是否启用趋势反转检测
            enableDrawdownProtection: 是否启用动态回撤保护
            enableSmartTrailing: 是否启用智能移动止损
            reversalSensitivity: 反转检测灵敏度

        Returns:
            (交易记录列表, 分析次数)
        """
        trades = []
        position = None  # 当前持仓
        analysis_count = 0  # 分析次数

        # 步骤1: 初始化 - 获取9小时初始数据作为基准
        if len(klines) < 9:
            raise ValueError("回测数据不足，需要至少9小时的数据")

        # 初始窗口：前9小时数据
        initial_klines = klines[:9]

        # 生成初始K线图
        chart_path = self.chart_service.generate_candlestick_chart(
            symbol=symbol,
            klines_data=initial_klines,
            chart_type='candlestick',
            show_volume=True
        )

        # 步骤2: 从第9小时开始，逐根K线进行递进分析
        for i in range(9, len(klines)):
            current_kline = klines[i]

            # 滑动窗口：包含所有历史数据
            historical_data = klines[:i+1]

            # 重新生成K线图（包含完整历史）
            chart_path = self.chart_service.generate_candlestick_chart(
                symbol=symbol,
                klines_data=historical_data,
                chart_type='candlestick',
                show_volume=True
            )

            # 获取AI分析
            result = self.ai_service.analyze_klines_with_ai(
                symbol=symbol,
                interval=interval,
                limit=len(historical_data),
                chart_type='candlestick'
            )

            analysis_count += 1

            if result['code'] == 200:
                action = result['data']['analysis'].get('action', 'hold')

                # 执行交易逻辑
                if position is None:  # 无持仓
                    if action in ['long', 'Long', 'LONG']:
                        # 开仓做多
                        position = {
                            'action': 'long',
                            'open_time': current_kline['open_time'],
                            'open_price': current_kline['close'],
                            'open_index': i,
                            'highest_price': current_kline['close'],  # 记录最高价
                            'lowest_price': current_kline['close'],   # 记录最低价
                            'stop_loss': result['data']['analysis'].get('stopLoss'),  # 止损价格
                            'take_profit': result['data']['analysis'].get('takeProfit'),  # 止盈价格
                            'measure_move': self._safe_float_convert(result['data']['analysis'].get('measureMove')),  # Measure Move目标位
                            'trailing_stop_price': None,  # 移动止损价格
                            'profit_target_reached': False,  # 是否达到盈利目标
                            'trailing_stop_active': False,  # 移动止损是否激活
                            'profitStop': profitStop,  # 移动止盈触发百分比
                            # v0.2.6 新增字段
                            'max_profit': 0.0,  # 最大盈利
                            'max_profit_price': current_kline['close'],  # 最大盈利时价格
                            'reversal_signals': [],  # 反转信号列表
                            'trend_reversal_detected': False,  # 是否检测到趋势反转
                            'drawdown_protection_active': False,  # 回撤保护是否激活
                            'smart_trailing_enabled': enableSmartTrailing,  # 智能移动止损是否启用
                            'ema_fast': None,  # 快线EMA值
                            'ema_slow': None,  # 慢线EMA值
                            'macd_line': None,  # MACD线
                            'signal_line': None,  # 信号线
                            'histogram': None,  # MACD柱状图
                            'atr_value': None  # ATR值
                        }
                    elif action in ['short', 'Short', 'SHORT']:
                        # 开仓做空
                        position = {
                            'action': 'short',
                            'open_time': current_kline['open_time'],
                            'open_price': current_kline['close'],
                            'open_index': i,
                            'highest_price': current_kline['close'],  # 记录最高价
                            'lowest_price': current_kline['close'],   # 记录最低价
                            'stop_loss': result['data']['analysis'].get('stopLoss'),  # 止损价格
                            'take_profit': result['data']['analysis'].get('takeProfit'),  # 止盈价格
                            'measure_move': self._safe_float_convert(result['data']['analysis'].get('measureMove')),  # Measure Move目标位
                            'trailing_stop_price': None,  # 移动止损价格
                            'profit_target_reached': False,  # 是否达到盈利目标
                            'trailing_stop_active': False,  # 移动止损是否激活
                            'profitStop': profitStop,  # 移动止盈触发百分比
                            # v0.2.6 新增字段
                            'max_profit': 0.0,  # 最大盈利
                            'max_profit_price': current_kline['close'],  # 最大盈利时价格
                            'reversal_signals': [],  # 反转信号列表
                            'trend_reversal_detected': False,  # 是否检测到趋势反转
                            'drawdown_protection_active': False,  # 回撤保护是否激活
                            'smart_trailing_enabled': enableSmartTrailing,  # 智能移动止损是否启用
                            'ema_fast': None,  # 快线EMA值
                            'ema_slow': None,  # 慢线EMA值
                            'macd_line': None,  # MACD线
                            'signal_line': None,  # 信号线
                            'histogram': None,  # MACD柱状图
                            'atr_value': None  # ATR值
                        }
                    # 如果是hold或close，不做任何操作
                else:  # 有持仓
                    # 更新最高价和最低价（持仓期间记录极值）
                    position['highest_price'] = max(position['highest_price'], current_kline['high'])
                    position['lowest_price'] = min(position['lowest_price'], current_kline['low'])

                    # v0.2.6: 更新技术指标
                    self._update_technical_indicators(position, klines[:i+1])

                    # 检查止损止盈价格（最高优先级）
                    exit_by_sl_tp = self._check_stop_loss_take_profit(position, current_kline)
                    if exit_by_sl_tp:
                        # 止损止盈平仓
                        self._close_position(position, current_kline, trades, exit_by_sl_tp)
                        position = None
                        continue

                    # v0.2.6: 检查趋势反转（第二优先级）
                    if enableTrendReversal:
                        reversal_exit_reason = self._check_trend_reversal(position, current_kline, reversalSensitivity)
                        if reversal_exit_reason:
                            self._close_position(position, current_kline, trades, reversal_exit_reason)
                            position = None
                            continue

                    # v0.2.6: 检查动态回撤保护（第三优先级）
                    if enableDrawdownProtection:
                        drawdown_exit_reason = self._check_drawdown_protection(position, current_kline)
                        if drawdown_exit_reason:
                            self._close_position(position, current_kline, trades, drawdown_exit_reason)
                            position = None
                            continue

                    # 检查时间止损（持仓时间过长）
                    time_exit_reason = self._check_time_stop(position, current_kline)
                    if time_exit_reason:
                        self._close_position(position, current_kline, trades, time_exit_reason)
                        position = None
                        continue

                    # 检查分批止盈条件
                    partial_close_reason = self._check_partial_close(position, current_kline)
                    if partial_close_reason:
                        self._close_position(position, current_kline, trades, partial_close_reason)
                        position = None
                        continue

                    if action == 'close' or (position['action'] == 'long' and action == 'short') or (position['action'] == 'short' and action == 'long'):
                        # 平仓（无论是主动close还是反向信号）
                        self._close_position(position, current_kline, trades, "AI信号")
                        position = None  # 清空持仓
                    elif action in ['long', 'Long', 'LONG'] and position['action'] == 'long':
                        # 继续持有做多，无需操作
                        pass
                    elif action in ['short', 'Short', 'SHORT'] and position['action'] == 'short':
                        # 继续持有做空，无需操作
                        pass
                    elif action == 'hold':
                        # 继续持有，无需操作
                        pass

        # 处理未平仓的最后一个位置
        if position is not None:
            # 在回测结束时强制平仓
            last_kline = klines[-1]
            position['close_time'] = last_kline['open_time']
            position['close_price'] = last_kline['close']
            position['close_index'] = len(klines) - 1

            # 计算盈亏（做空时盈亏计算相反）
            if position['action'] == 'long':
                profit = position['close_price'] - position['open_price']

                # 计算最大盈利和最大亏损
                max_profit = position['highest_price'] - position['open_price']
                max_loss = position['open_price'] - position['lowest_price']
            else:  # short
                profit = position['open_price'] - position['close_price']

                # 计算最大盈利和最大亏损（做空相反）
                max_profit = position['open_price'] - position['lowest_price']
                max_loss = position['highest_price'] - position['open_price']

            # 计算盈亏比（盈利/亏损的比值，避免除零）
            if max_loss > 0:
                profit_ratio = round(abs(max_profit / max_loss), 2)
            else:
                profit_ratio = float('inf') if max_profit > 0 else 0

            # 判断离场原因（强制平仓，视为时间止损）
            exit_reason = "时间止损" if profit < 0 else "时间止盈"

            period = self._format_period(
                position['open_time'],
                position['close_time']
            )

            trades.append({
                'action': position['action'],
                'period': period,
                'profit': round(profit, 2),
                'openPrice': position['open_price'],
                'closePrice': position['close_price'],
                'exitReason': exit_reason,  # 离场原因
                'profitRatio': profit_ratio  # 盈亏比
            })

        return trades, analysis_count

    def _check_stop_loss_take_profit(self, position: Dict, current_kline: Dict) -> Optional[str]:
        """
        检查是否触及止损止盈价格（包含智能止盈策略）

        Args:
            position: 持仓信息
            current_kline: 当前K线数据

        Returns:
            如果触及止损止盈，返回离场原因；否则返回None
        """
        current_high = current_kline['high']
        current_low = current_kline['low']

        # === v0.2.6 离场优先级 ===
        # 1. 基础止损（最高优先级，必须立即执行）
        if position['action'] == 'long':
            # 做多：止损价为更低价格
            if position.get('stop_loss') and current_low <= position['stop_loss']:
                return "止损"
        else:  # short
            # 做空：止损价为更高价格
            if position.get('stop_loss') and current_high >= position['stop_loss']:
                return "止损"

        # 2. Measure Move止盈（AI分析的精确目标位，到达后坚决止盈！）
        measure_move_result = self._check_measure_move(position, current_high, current_low)
        if measure_move_result:
            return measure_move_result

        # 3. 智能移动止损（v0.2.6: 基于ATR动态调整）
        trailing_result = self._check_trailing_stop(position, current_high, current_low)
        if trailing_result:
            return trailing_result

        # 4. 基础止盈（传统的固定价格止盈）
        if position['action'] == 'long':
            if position.get('take_profit') and current_high >= position['take_profit']:
                return "止盈"
        else:  # short
            if position.get('take_profit') and current_low <= position['take_profit']:
                return "止盈"

        return None

    def _check_trailing_stop(self, position: Dict, current_high: float, current_low: float) -> Optional[str]:
        """
        检查移动止损策略（v0.2.6: 支持智能调整）

        Args:
            position: 持仓信息
            current_high: 当前最高价
            current_low: 当前最低价

        Returns:
            如果触及移动止损，返回离场原因；否则返回None
        """
        if not position.get('trailing_stop_active', False):
            # 检查是否需要激活移动止损（盈利达到profitStop%时激活）
            profitStop_pct = position.get('profitStop', 20.0)

            if position['action'] == 'long':
                # 计算当前盈利百分比
                current_profit_pct = (current_high - position['open_price']) / position['open_price'] * 100
                # 如果盈利达到profitStop%，激活移动止损
                if current_profit_pct >= profitStop_pct:
                    position['profit_target_reached'] = True
                    position['trailing_stop_active'] = True
                    # v0.2.6: 智能移动止损设置
                    target_profit_amount = position['open_price'] * (profitStop_pct / 100)
                    trailing_price = self._calculate_smart_trailing_price(
                        position, 'long', position['open_price'], target_profit_amount
                    )
                    position['trailing_stop_price'] = trailing_price
                    return None  # 未触及止损，继续持有
            else:  # short
                # 计算当前盈利百分比（做空相反）
                current_profit_pct = (position['open_price'] - current_low) / position['open_price'] * 100
                # 如果盈利达到profitStop%，激活移动止损
                if current_profit_pct >= profitStop_pct:
                    position['profit_target_reached'] = True
                    position['trailing_stop_active'] = True
                    # v0.2.6: 智能移动止损设置
                    target_profit_amount = position['open_price'] * (profitStop_pct / 100)
                    trailing_price = self._calculate_smart_trailing_price(
                        position, 'short', position['open_price'], target_profit_amount
                    )
                    position['trailing_stop_price'] = trailing_price
                    return None  # 未触及止损，继续持有

        # 移动止损已激活，检查是否触及
        if position.get('trailing_stop_active', False):
            if position['action'] == 'long':
                # 做多：移动止损只上调，不下调
                if current_low <= position['trailing_stop_price']:
                    position['trailing_stop_price'] = current_low
                    return "移动止盈"
                # v0.2.6: 智能移动止损更新
                self._update_smart_trailing_stop(position, 'long', current_high, current_low)
            else:  # short
                # 做空：移动止损只下调，不上调
                if current_high >= position['trailing_stop_price']:
                    position['trailing_stop_price'] = current_high
                    return "移动止盈"
                # v0.2.6: 智能移动止损更新
                self._update_smart_trailing_stop(position, 'short', current_high, current_low)

        return None

    def _calculate_smart_trailing_price(self, position: Dict, action: str, open_price: float, target_profit: float) -> float:
        """
        v0.2.6: 计算智能移动止损价格

        Args:
            position: 持仓信息
            action: 操作方向 ('long' 或 'short')
            open_price: 开仓价格
            target_profit: 目标盈利

        Returns:
            智能移动止损价格
        """
        # 基础移动止损：盈利的80%
        base_trailing = open_price + (target_profit * 0.8) if action == 'long' else open_price - (target_profit * 0.8)

        # v0.2.6: 基于ATR的智能调整
        atr_value = position.get('atr_value')
        smart_trailing_enabled = position.get('smart_trailing_enabled', True)

        if smart_trailing_enabled and atr_value:
            # 计算波动率因子
            volatility_factor = (atr_value / open_price) * 100

            # 基于波动率调整移动止损距离
            if volatility_factor > 2.0:  # 高波动
                # 更宽的止损距离
                multiplier = 2.5
            elif volatility_factor < 0.5:  # 低波动
                # 更紧的止损距离
                multiplier = 1.5
            else:  # 中等波动
                multiplier = 2.0

            # 重新计算移动止损
            if action == 'long':
                # 做多：基于ATR向上调整止损
                smart_trailing = open_price + (target_profit * 0.8 * multiplier / 2.0)
            else:
                # 做空：基于ATR向下调整止损
                smart_trailing = open_price - (target_profit * 0.8 * multiplier / 2.0)

            return smart_trailing

        return base_trailing

    def _update_smart_trailing_stop(self, position: Dict, action: str, current_high: float, current_low: float) -> None:
        """
        v0.2.6: 更新智能移动止损

        Args:
            position: 持仓信息
            action: 操作方向
            current_high: 当前最高价
            current_low: 当前最低价
        """
        smart_trailing_enabled = position.get('smart_trailing_enabled', True)
        atr_value = position.get('atr_value')

        if not smart_trailing_enabled or not atr_value:
            # 传统移动止损更新
            if action == 'long':
                new_trailing_price = position['trailing_stop_price']
                if current_low > new_trailing_price:
                    position['trailing_stop_price'] = min(current_low * 0.95, current_high * 0.95)
            else:
                new_trailing_price = position['trailing_stop_price']
                if current_high < new_trailing_price:
                    position['trailing_stop_price'] = max(current_high * 1.05, current_low * 1.05)
            return

        # v0.2.6: 智能移动止损更新
        current_price = (current_high + current_low) / 2
        volatility_factor = (atr_value / current_price) * 100

        # 根据波动率动态调整移动止损紧密度
        if action == 'long':
            new_trailing_price = position['trailing_stop_price']
            if current_low > new_trailing_price:
                # 基于波动率调整止损更新幅度
                if volatility_factor > 2.0:  # 高波动，更保守
                    position['trailing_stop_price'] = min(current_low * 0.92, current_high * 0.92)
                elif volatility_factor < 0.5:  # 低波动，更激进
                    position['trailing_stop_price'] = min(current_low * 0.97, current_high * 0.97)
                else:
                    position['trailing_stop_price'] = min(current_low * 0.95, current_high * 0.95)
        else:
            new_trailing_price = position['trailing_stop_price']
            if current_high < new_trailing_price:
                # 基于波动率调整止损更新幅度
                if volatility_factor > 2.0:  # 高波动，更保守
                    position['trailing_stop_price'] = max(current_high * 1.08, current_low * 1.08)
                elif volatility_factor < 0.5:  # 低波动，更激进
                    position['trailing_stop_price'] = max(current_high * 1.03, current_low * 1.03)
                else:
                    position['trailing_stop_price'] = max(current_high * 1.05, current_low * 1.05)


    def _check_time_stop(self, position: Dict, current_kline: Dict) -> Optional[str]:
        """
        检查时间止损（避免持仓时间过长）

        Args:
            position: 持仓信息
            current_kline: 当前K线数据

        Returns:
            如果超过时间限制，返回离场原因；否则返回None
        """
        # 计算持仓时间（小时）
        open_time = datetime.fromtimestamp(position['open_time'] / 1000)
        current_time = datetime.fromtimestamp(current_kline['close_time'] / 1000)
        holding_hours = (current_time - open_time).total_seconds() / 3600

        # 如果持仓超过48小时，触发时间止损
        if holding_hours > 48:
            return "时间止损"

        return None

    def _check_partial_close(self, position: Dict, current_kline: Dict) -> Optional[str]:
        """
        检查分批止盈条件

        Args:
            position: 持仓信息
            current_kline: 当前K线数据

        Returns:
            如果满足分批止盈条件，返回离场原因；否则返回None
        """
        if position.get('trailing_stop_active', False):
            # 如果移动止损已激活，检查是否需要分批止盈
            current_profit = 0
            if position['action'] == 'long':
                current_profit = (current_kline['close'] - position['open_price']) / position['open_price'] * 100
            else:  # short
                current_profit = (position['open_price'] - current_kline['close']) / position['open_price'] * 100

            # 如果盈利超过20%，开始考虑分批止盈
            if current_profit > 20:
                # 这里可以实现分批止盈逻辑，比如每盈利10%就平仓25%的仓位
                # 目前简化为全部平仓
                return "分批止盈"

        return None

    def _close_position(self, position: Dict, current_kline: Dict, trades: List[Dict], exit_reason: str) -> None:
        """
        执行平仓操作

        Args:
            position: 持仓信息
            current_kline: 当前K线数据
            trades: 交易记录列表
            exit_reason: 离场原因
        """
        position['close_time'] = current_kline['open_time']
        position['close_price'] = current_kline['close']
        position['close_index'] = len(trades)  # 临时用索引

        # 计算盈亏（做空时盈亏计算相反）
        if position['action'] == 'long':
            profit = position['close_price'] - position['open_price']

            # 计算最大盈利和最大亏损（多头相反）
            max_profit = position['highest_price'] - position['open_price']
            max_loss = position['open_price'] - position['lowest_price']
        else:  # short
            profit = position['open_price'] - position['close_price']

            # 计算最大盈利和最大亏损（做空相反）
            max_profit = position['open_price'] - position['lowest_price']
            max_loss = position['highest_price'] - position['open_price']

        # 计算盈亏比（盈利/亏损的比值，避免除零）
        if max_loss > 0:
            profit_ratio = round(abs(max_profit / max_loss), 2)
        else:
            profit_ratio = float('inf') if max_profit > 0 else 0

        period = self._format_period(
            position['open_time'],
            position['close_time']
        )

        trades.append({
            'action': position['action'],
            'period': period,
            'profit': round(profit, 2),
            'openPrice': position['open_price'],
            'closePrice': position['close_price'],
            'exitReason': exit_reason,  # 离场原因
            'profitRatio': profit_ratio  # 盈亏比
        })

    def _format_period(self, start_time: int, end_time: int) -> str:
        """
        格式化交易周期

        Args:
            start_time: 开始时间戳
            end_time: 结束时间戳

        Returns:
            格式化的时间周期字符串
        """
        start_dt = datetime.fromtimestamp(start_time / 1000)
        end_dt = datetime.fromtimestamp(end_time / 1000)

        return f"{start_dt.strftime('%Y-%m-%d %H:%M')} - {end_dt.strftime('%Y-%m-%d %H:%M')}"

    def _update_technical_indicators(self, position: Dict, klines: List[Dict]) -> None:
        """
        v0.2.6: 更新技术指标

        Args:
            position: 持仓信息
            klines: K线数据
        """
        if len(klines) < 26:
            # 数据不足，跳过指标计算
            return

        # 提取价格数据
        closes = [k['close'] for k in klines]
        highs = [k['high'] for k in klines]
        lows = [k['low'] for k in klines]

        # 计算EMA
        if len(klines) >= 26:
            ema_fast_list = calculate_ema(closes, 12)
            ema_slow_list = calculate_ema(closes, 26)

            if len(ema_fast_list) > 0:
                position['ema_fast'] = ema_fast_list[-1]
            if len(ema_slow_list) > 0:
                position['ema_slow'] = ema_slow_list[-1]

        # 计算MACD
        if len(klines) >= 26:
            macd_data = calculate_macd(closes)
            if macd_data['macd_line'] and len(macd_data['macd_line']) > 0:
                position['macd_line'] = macd_data['macd_line'][-1]
                position['signal_line'] = macd_data['signal_line'][-1]
                position['histogram'] = macd_data['histogram'][-1]

        # 计算ATR
        if len(klines) >= 14:
            atr_list = calculate_atr(highs, lows, closes, 14)
            if len(atr_list) > 0:
                position['atr_value'] = atr_list[-1]

    def _check_trend_reversal(self, position: Dict, current_kline: Dict, sensitivity: str) -> Optional[str]:
        """
        v0.2.6: 检查趋势反转

        Args:
            position: 持仓信息
            current_kline: 当前K线数据
            sensitivity: 灵敏度 ('low', 'medium', 'high')

        Returns:
            如果检测到趋势反转，返回离场原因；否则返回None
        """
        signals = []
        current_price = current_kline['close']

        # 1. EMA交叉检测
        if position.get('ema_fast') is not None and position.get('ema_slow') is not None:
            ema_fast = position['ema_fast']
            ema_slow = position['ema_slow']

            if position['action'] == 'long':
                # 做多时，EMA快线从上下穿慢线
                if ema_fast < ema_slow:
                    signals.append("EMA交叉")
            else:
                # 做空时，EMA快线从下上穿慢线
                if ema_fast > ema_slow:
                    signals.append("EMA交叉")

        # 2. MACD背离检测（简化版）
        if position.get('macd_line') is not None and position.get('signal_line') is not None:
            macd_line = position['macd_line']
            signal_line = position['signal_line']

            if position['action'] == 'long':
                # 做多时，MACD线从上向下穿越信号线
                if macd_line < signal_line:
                    signals.append("MACD交叉")
            else:
                # 做空时，MACD线从下向上穿越信号线
                if macd_line > signal_line:
                    signals.append("MACD交叉")

        # 3. 价格行为检测（简化版）
        if position.get('highest_price') and position.get('lowest_price'):
            price_range = position['highest_price'] - position['lowest_price']
            current_position_in_range = 0

            if price_range > 0:
                if position['action'] == 'long':
                    current_position_in_range = (current_price - position['lowest_price']) / price_range
                    # 做多时，价格跌回区间下轨
                    if current_position_in_range < 0.3:
                        signals.append("价格行为")
                else:
                    current_position_in_range = (position['highest_price'] - current_price) / price_range
                    # 做空时，价格涨回区间上轨
                    if current_position_in_range < 0.3:
                        signals.append("价格行为")

        # 记录反转信号
        position['reversal_signals'] = signals

        # 根据灵敏度判断是否离场
        if not signals:
            return None

        # 不同灵敏度需要不同的信号数量
        signal_threshold = {
            'low': 3,      # 需要3个信号才离场
            'medium': 2,   # 需要2个信号才离场（默认）
            'high': 1      # 只需1个信号就离场
        }

        threshold = signal_threshold.get(sensitivity, 2)

        if len(signals) >= threshold:
            return f"趋势反转-{'+'.join(signals[:2])}"  # 最多显示2个信号

        return None

    def _check_drawdown_protection(self, position: Dict, current_kline: Dict) -> Optional[str]:
        """
        v0.2.6: 检查动态回撤保护

        Args:
            position: 持仓信息
            current_kline: 当前K线数据

        Returns:
            如果触发回撤保护，返回离场原因；否则返回None
        """
        current_price = current_kline['close']
        open_price = position['open_price']

        # 计算当前盈利
        if position['action'] == 'long':
            current_profit = current_price - open_price
            max_profit = position.get('max_profit', 0)
            max_profit_price = position.get('max_profit_price', open_price)

            # 更新最大盈利
            if current_profit > max_profit:
                max_profit = current_profit
                max_profit_price = current_price
                position['max_profit'] = max_profit
                position['max_profit_price'] = max_profit_price
                position['drawdown_protection_active'] = True

            # 计算回撤百分比
            if max_profit > 0:
                profit_drawdown = (max_profit - current_profit) / max_profit

                # 动态回撤阈值
                max_profit_pct = (max_profit / open_price) * 100

                if max_profit_pct < 5:
                    threshold = 1.0  # 100%回撤容忍（盈利太少）
                elif max_profit_pct < 10:
                    threshold = 0.5  # 50%回撤容忍
                elif max_profit_pct < 20:
                    threshold = 0.4  # 40%回撤容忍
                elif max_profit_pct < 30:
                    threshold = 0.3  # 30%回撤容忍
                elif max_profit_pct < 50:
                    threshold = 0.25  # 25%回撤容忍
                else:
                    threshold = 0.2  # 20%回撤容忍（最高盈利时）

                # 紧急止损：超过20%回撤直接离场
                if profit_drawdown > 0.2:
                    return "紧急止损-最大回撤"

                # 动态回撤保护
                if profit_drawdown > threshold:
                    return f"动态回撤保护-{int(profit_drawdown * 100)}%"

        else:  # short
            current_profit = open_price - current_price
            max_profit = position.get('max_profit', 0)
            max_profit_price = position.get('max_profit_price', open_price)

            # 更新最大盈利
            if current_profit > max_profit:
                max_profit = current_profit
                max_profit_price = current_price
                position['max_profit'] = max_profit
                position['max_profit_price'] = max_profit_price
                position['drawdown_protection_active'] = True

            # 计算回撤百分比
            if max_profit > 0:
                profit_drawdown = (max_profit - current_profit) / max_profit

                # 动态回撤阈值
                max_profit_pct = (max_profit / open_price) * 100

                if max_profit_pct < 5:
                    threshold = 1.0  # 100%回撤容忍
                elif max_profit_pct < 10:
                    threshold = 0.5  # 50%回撤容忍
                elif max_profit_pct < 20:
                    threshold = 0.4  # 40%回撤容忍
                elif max_profit_pct < 30:
                    threshold = 0.3  # 30%回撤容忍
                elif max_profit_pct < 50:
                    threshold = 0.25  # 25%回撤容忍
                else:
                    threshold = 0.2  # 20%回撤容忍

                # 紧急止损：超过20%回撤直接离场
                if profit_drawdown > 0.2:
                    return "紧急止损-最大回撤"

                # 动态回撤保护
                if profit_drawdown > threshold:
                    return f"动态回撤保护-{int(profit_drawdown * 100)}%"

        return None

    def _check_measure_move(self, position: Dict, current_high: float, current_low: float) -> Optional[str]:
        """
        v0.2.6: 检查Measure Move目标止盈

        Args:
            position: 持仓信息
            current_high: 当前最高价
            current_low: 当前最低价

        Returns:
            如果触及Measure Move目标，返回离场原因；否则返回None
        """
        measure_move_price = position.get('measure_move')

        # 如果没有设置measure move，跳过检查
        if not measure_move_price:
            return None

        # 检查是否触及measure move目标位
        if position['action'] == 'long':
            # 做多：价格达到或超过measure move目标位
            if current_high >= measure_move_price:
                return "Measure Move止盈"
        else:  # short
            # 做空：价格达到或低于measure move目标位
            if current_low <= measure_move_price:
                return "Measure Move止盈"

        return None

    def _safe_float_convert(self, value) -> Optional[float]:
        """
        安全地将值转换为浮点数

        Args:
            value: 要转换的值（可能是字符串、数字或None）

        Returns:
            转换后的浮点数，如果转换失败则返回None
        """
        if value is None:
            return None

        if isinstance(value, (int, float)):
            return float(value)

        if isinstance(value, str):
            try:
                return float(value)
            except (ValueError, TypeError):
                return None

        return None

